package zhoug.demo.player;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import zhoug.common.utils.StringUtils;
import zhoug.logging.Logger;
import zhoug.player.core.Callback;
import zhoug.player.core.CameraToken;
import zhoug.player.core.OnPlayListener;
import zhoug.player.core.PlayError;
import zhoug.player.core.RecordSegment;
import zhoug.player.core.ZPlayer;
import zhoug.player.core.utils.CalendarUtil;
import zhoug.player.core.widget.TimeBarView;
import zhoug.player.core.widget.VideoRatioTextureView;
import zhoug.player.exo.ExoPlayerHelper;
import zhoug.player.hikvision.HikPlayerHelper;
import zhoug.player.qly.QlyPlayerHelper;
import zhoug.player.qly.QlySdk;
import zhoug.player.qly.QlyTokenParams;
import zhoug.player.tx.TxPlayerHelper;
import zhoug.player.vlc.VLCPlayerHelper;
import zhoug.zui.ZUITopView;
import zhoug.zui.date.DateSelectInterface;
import zhoug.zui.dialog.date.ZUIMultiDateChooser;
import zhoug.zui.ints.OnItemClickListener;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Author: zhoug
 * @Date: 2024-12-06
 * @Description:
 */
@SuppressLint("UnsafeOptInUsageError")
public class PlayerActivity extends MyBaseActivity {
    public static final String PARAM_PLAYER_TYPE = "player_type";
    private int mPlayerType;
    private boolean mPlayBtnStatus = false;
    private boolean retry = true;
    private boolean isPlayback = false;//标记是否回放
    private long mStartTime;
    private long mEndTime;
    private long mPendingStartTime;
    private long mPendingEndTime;
    private UpdateTimeHelper mUpdateTimeHelper;

    private ZPlayer mPlayer;
    private PlayData mPlayData;
    private PlayDataListDialog mPlayDataListDialog;
    private ZUITopView mTopView;
    private VideoRatioTextureView mTextureView;
    private FrameLayout mContainerTextureView;
    private ProgressBar mLoading;
    private ImageView mBtnPlay;
    private TextView mTvError;
    private RelativeLayout mContainerVideo;
    private Button mBtnStartPlay;
    private Button mBtnStopPlay;
    private Button mBtnPausePlay;
    private Button mBtnMute;
    private Button mBtnScreenshot;
    private Button mBtnRecording;
    private Button mBtnRelease;
    private Button mBtnUrls;
    private TextView mTvName;
    private Button mBtnInitPlayer;
    private TimeBarView mTimeBar;
    private TextView mBtnPlaybackTime;

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_player;
    }

    @Override
    protected void findViews() {
        mTopView = findViewById(R.id.topView);
        mTextureView = findViewById(R.id.textureView);
        mContainerTextureView = findViewById(R.id.container_textureView);
        mLoading = findViewById(R.id.loading);
        mBtnPlay = findViewById(R.id.btn_play);
        mTvError = findViewById(R.id.tv_error);
        mContainerVideo = findViewById(R.id.container_video);
        mBtnStartPlay = findViewById(R.id.btn_startPlay);
        mBtnStopPlay = findViewById(R.id.btn_stopPlay);
        mBtnPausePlay = findViewById(R.id.btn_pausePlay);
        mBtnMute = findViewById(R.id.btn_mute);
        mBtnScreenshot = findViewById(R.id.btn_screenshot);
        mBtnRecording = findViewById(R.id.btn_recording);
        mBtnRelease = findViewById(R.id.btn_release);
        mBtnUrls = findViewById(R.id.btn_urls);
        mTvName = findViewById(R.id.tv_name);
        mBtnInitPlayer = findViewById(R.id.btn_initPlayer);
        mTimeBar = findViewById(R.id.time_bar);
        mBtnPlaybackTime = findViewById(R.id.btn_playbackTime);
    }

    @Override
    protected void onCreate1(Bundle savedInstanceState) {
        Intent intent = getIntent();
        if (null != intent) {
            mPlayerType = intent.getIntExtra(PARAM_PLAYER_TYPE, PlayerType.EXO);
        }
        mPlayDataListDialog = new PlayDataListDialog(this);
        List<PlayData> playDataList = PlayData.getPlayDataList();

        mPlayDataListDialog.setData(playDataList);
        mPlayDataListDialog.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                PlayData itemData = mPlayDataListDialog.getItemData(position);
                if (mPlayData == null || !mPlayData.equals(itemData)) {
                    stopPlay();
                    setPlayName(itemData);
                    mPlayData = itemData;
                    retry = true;
                    startPlay();
                } else {
                    toast("请选择其它视频");
                }

            }
        });
        mBtnInitPlayer.setOnClickListener(v -> {
            initPlayer();
        });
        //选择播放源
        mBtnUrls.setOnClickListener(v -> {
            mPlayDataListDialog.show();
        });
        //播放/暂停
        mBtnPlay.setOnClickListener(v -> {
            retry = true;
            startOrPausePlay();
        });
        //播放
        mBtnStartPlay.setOnClickListener(v -> {
            retry = true;
            startPlay();
        });
        //停止播放
        mBtnStopPlay.setOnClickListener(v -> {
            retry = true;
            stopPlay();

        });
        //暂停播放
        mBtnPausePlay.setOnClickListener(v -> {
            retry = true;
            pausePlay();

        });
        //静音
        mBtnMute.setOnClickListener(v -> {
            if (!isRelease()) {
                if (mPlayer.isMute()) {
                    mBtnMute.setText("静音(关)");
                    mPlayer.setMute(false);
                } else {
                    mBtnMute.setText("静音(开)");
                    mPlayer.setMute(true);
                }
            }

        });
        //释放资源
        mBtnRelease.setOnClickListener(v -> {
            release();
        });
        //选择回放时间
        mBtnPlaybackTime.setOnClickListener(v -> {
            ZUIMultiDateChooser chooser = new ZUIMultiDateChooser(this);
            chooser.setStartTime(CalendarUtil.timeToyyyy_MM_dd_HH_mm(mStartTime));
            chooser.setEndTime(CalendarUtil.timeToyyyy_MM_dd_HH_mm(mEndTime));
            chooser.setDateMode(ZUIMultiDateChooser.MODE_DATE_TIME);
            chooser.setOrientation(DateSelectInterface.HORIZONTAL);
            chooser.setCallback(new ZUIMultiDateChooser.Callback() {
                @Override
                public void onSelectDate(String startTime, String endTime) {
                    mBtnPlaybackTime.setText(StringUtils.format("%s 至 %s", startTime, endTime));
                    mPendingStartTime = CalendarUtil.yyyy_MM_dd_HH_mmToLong(startTime);
                    mPendingEndTime = CalendarUtil.yyyy_MM_dd_HH_mmToLong(endTime);
                    mTimeBar.setFileInfoList(null);
                    mStartTime = 0;
                    mEndTime = 0;
                    getTimelineSectionList();
                }
            });
            chooser.show();
        });

        initPlayer();
        if (mPlayer instanceof QlyPlayerHelper qlyPlayerHelper) {
            mUpdateTimeHelper = new UpdateTimeHelper(mTimeBar, qlyPlayerHelper);
            mUpdateTimeHelper.setonUpdateTimeListener(new UpdateTimeHelper.OnUpdateTimeListener() {
                @Override
                public void onUpdateTime(long currentTime) {
                    String currentTimeStr = CalendarUtil.timeToyyyy_MM_dd_HH_mm_ss(currentTime);
                    Log.d(TAG, "onUpdateTime:" + currentTimeStr);
//                mTvCurrentTime.setText(currentTimeStr);
                }
            });

            mPlayData = playDataList.get(playDataList.size() - 1);
            String playUrl = mPlayData.getPlayUrl();
            mPlayer.setPlayUrl(playUrl);
            getOpenPlatformToken(new Callback<Boolean>() {
                @Override
                public void onSuccess(Boolean qlyToken) {
                    mPlayer.startPlay();
                }

                @Override
                public void onError(int status, String error) {
                    if (status == PlayError.TOKEN_EXPIRE) {
                        SharedPreferencesUtils.setMonitorToken(playUrl, null);
                        toast("重新获取token");
                        getTokenFromServer(new Callback<Boolean>() {
                            @Override
                            public void onSuccess(Boolean aBoolean) {
                                mPlayer.startPlay();
                            }

                            @Override
                            public void onError(int status, String error) {
                                Log.e(TAG, "获取token失败:" + error);

                            }
                        });
                    } else {
                        hideLoading();
                        Log.e(TAG, "获取token失败:" + error);
                        toast(error);
                    }

                }
            });
        } else {
            mPlayData = playDataList.get(0);
            startPlay();
        }
        setPlayName(mPlayData);

    }


    private void initPlayer() {
        switch (mPlayerType) {
            case PlayerType.HIK:
                mTopView.setTitle("海康播放器");
                mPlayer = new HikPlayerHelper();
                break;
            case PlayerType.TX:
                mTopView.setTitle("腾讯播放器");
                mPlayer = new TxPlayerHelper();
                break;
            case PlayerType.VLC:
                mTopView.setTitle("VLC播放器");
                mPlayer = new VLCPlayerHelper();
                break;
            case PlayerType.QLY:
                mTopView.setTitle("千里眼播放器");
                mPlayer = new QlyPlayerHelper();
                break;
            default:
                mTopView.setTitle("EXO播放器");
                mPlayer = new ExoPlayerHelper();
                break;
        }
        mPlayer.setContext(this);
        mPlayer.setVideoTextureView(mTextureView);
        mPlayer.setPlayViewGroup(mContainerTextureView);
        mPlayer.setOnPlayListener(new OnPlayListener() {
            @Override
            public void onPlayStatusChange(int state) {
                switch (state) {
                    case ZPlayer.STATE_IDLE://播放器处于初始状态
                        Logger.d(TAG, "播放器处于初始状态");
                        hideError();
                        hideLoading();
                        setPlayBtnStatus(false);
                        if (mUpdateTimeHelper != null)
                            mUpdateTimeHelper.stop();
                        break;
                    case ZPlayer.STATE_START://开始播放
                        Logger.d(TAG, "开始播放");

                        hideError();
                        showLoading();
                        setPlayBtnStatus(true);
                        break;
                    case ZPlayer.STATE_PREPARED://资源准备好了
                        Logger.d(TAG, "资源准备好了");
                        break;
                    case ZPlayer.STATE_PLAYING://正在播放
                        Logger.d(TAG, "正在播放");
                        hideError();
                        hideLoading();
                        setPlayBtnStatus(true);
                        if (isPlayback && mUpdateTimeHelper != null) {
                            mUpdateTimeHelper.start();
                        }
                        break;
                    case ZPlayer.STATE_PAUSE://暂停播放
                        Logger.d(TAG, "暂停播放");
                        hideError();
                        hideLoading();
                        setPlayBtnStatus(false);
                        if (mUpdateTimeHelper != null)
                            mUpdateTimeHelper.stop();
                        break;
                    case ZPlayer.STATE_ENDED://播放完成了
                        Logger.d(TAG, "播放完成了");
                        hideError();
                        hideLoading();
                        setPlayBtnStatus(false);
                        if (mUpdateTimeHelper != null)
                            mUpdateTimeHelper.stop();
                        break;
                }
            }

            @Override
            public void onPlayError(int code, String error) {
                if (mUpdateTimeHelper != null)
                    mUpdateTimeHelper.stop();

                Logger.e(TAG, "onPlayError:code=" + code + "error=" + error);
                if (retry && (code == PlayError.TOKEN_EXPIRE || "token无效".equals(error))) {
                    Log.e(TAG, "token 过期 重新获取");
                    retry = false;
                    getOpenPlatformToken(new Callback<Boolean>() {
                        @Override
                        public void onSuccess(Boolean success) {
                            hideError();
                            mPlayer.startPlay();
                        }

                        @Override
                        public void onError(int status, String error) {
                            showError(error);
                            hideLoading();
                            setPlayBtnStatus(false);

                        }
                    });
                } else {
                    showError(error);
                    hideLoading();
                    setPlayBtnStatus(false);
                }


            }

            @Override
            public void onVideoSizeChanged(int width, int height) {
                Logger.d(TAG, "onVideoSizeChanged:" + width + "," + height);
            }
        });

        mPlayer.setMute(true);


    }

    /**
     * 初始化时间选择器
     */
    private void initTimeBarView() {
        mTimeBar.setTimeBarCallback(new TimeBarView.SimpleTimePickedCallBack() {

            @Override
            public void onTimePickedCallback(long currentTime, boolean inFileInfoList) {
                if (isPlayback) {
                    if (inFileInfoList) {
                        playBack(currentTime);
                    } else {
                        //时间没有在片段时间内
                        //如果超出获取回放的起止时间则获取播放片段
                        if (currentTime < mStartTime) {
                            //左移
                            mPendingEndTime = mStartTime;
                            mPendingStartTime = mPendingEndTime - 24 * 60 * 60 * 1000;
                            getTimelineSectionList(currentTime);
                        } else if (currentTime > mEndTime) {
                            //右移
                            mPendingStartTime = mEndTime;
                            mPendingEndTime = mPendingStartTime + 24 * 60 * 60 * 1000;
                            long currentTimeMillis = System.currentTimeMillis();
                            if (mPendingEndTime > currentTimeMillis) {
                                mPendingEndTime = currentTimeMillis;
                            }
                            getTimelineSectionList(currentTime);
                        } else {
                            toast("当前时间没有录像片段");
                        }
                    }
                }

            }

            @Override
            public void onTimePickedCallback(long currentTime) {

            }
        });

    }

    private void getTimelineSectionList() {
        getTimelineSectionList(0);
    }

    /**
     * 获取云存储回放数据列表
     */
    private void getTimelineSectionList(long pendingPlayTime) {
        if (!(mPlayer instanceof QlyPlayerHelper)) {
            return;
        }
        QlyPlayerHelper qlyPlayerHelper = (QlyPlayerHelper) mPlayer;
        if (!(mPendingStartTime > 0 && mPendingEndTime > 0 && mPendingEndTime > mPendingStartTime)) {
            Log.d(TAG, "getTimelineSectionList:开始时间结束时间错误:" + mPendingStartTime + " - " + mPendingStartTime);
            return;
        }
        Log.d(TAG, "获取云存储回放数据列表:" + CalendarUtil.timeToyyyy_MM_dd_HH_mm_ss(mPendingStartTime) + " 至 " + CalendarUtil.timeToyyyy_MM_dd_HH_mm_ss(mPendingEndTime));
        qlyPlayerHelper.getTimelineSectionList(mPendingStartTime, mPendingEndTime, new Callback<List<RecordSegment>>() {
            @Override
            public void onSuccess(List<RecordSegment> recordSegments) {
                Log.d(TAG, "获取云存储回放数据列表成功:" + recordSegments.size() + "");
               /* for (RecordSegment item :recordSegments ) {
                    Log.d(TAG, "onSuccess:"+item.getBeginTime()+" 至 "+item.getEndTime());
                }*/
                //有回放片段
                if (!recordSegments.isEmpty()) {
                    List<RecordSegment> newRecordSegmentList = mTimeBar.getRecordSegmentList();
                    if (!newRecordSegmentList.isEmpty()) {
                        List<RecordSegment> all = new ArrayList<>(newRecordSegmentList);
                        all.addAll(recordSegments);
                        Collections.sort(all);
                        mTimeBar.setFileInfoList(all);
                        if (mPendingStartTime < mStartTime) {
                            mStartTime = mPendingStartTime;
                        }
                        if (mPendingEndTime > mEndTime) {
                            mEndTime = mPendingEndTime;
                        }
                    } else {
                        mStartTime = mPendingStartTime;
                        mEndTime = mPendingEndTime;
                        mTimeBar.setFileInfoList(recordSegments);
                    }
                    mBtnPlaybackTime.setText(StringUtils.format("%s 至 %s",
                            CalendarUtil.timeToyyyy_MM_dd_HH_mm(mStartTime),
                            CalendarUtil.timeToyyyy_MM_dd_HH_mm(mEndTime)));

                    if (pendingPlayTime > 0) {
                        if (mTimeBar.isInFileInfoList(pendingPlayTime)) {
                            playBack(pendingPlayTime);
                        }
                    } else {
                        RecordSegment startRecordSegment = mTimeBar.getStartRecordSegment();
                        if (startRecordSegment != null) {
                            playBack(startRecordSegment.getBeginTimeMillis());
                        }
                    }


                } else {
                    toast("选择的时间段没有录像片段");
                }

            }

            @Override
            public void onError(int code, String error) {
                Log.e(TAG, "获取云存储回放数据列表失败:" + error);
            }
        });
    }

    /**
     * 开始播放
     */
    private void startPlay() {
        if (!isRelease()) {
            if (mPlayer.isPlaying()) {
                toast("已经在播放了");
                return;
            }
            if (mPlayer.isPause()) {
                Logger.d(TAG, "恢复播放");
                mPlayer.resumePlay();
                return;
            }
            mPlayer.setPlayUrl(mPlayData.getPlayUrl());
            mPlayer.startPlay();
            Logger.d(TAG, "开始播放");
        }
    }

    /**
     * 开始或者暂停播放
     */
    private void startOrPausePlay() {
        if (!isRelease()) {
            if (mPlayer.isPlaying()) {
                pausePlay();
            } else {
                startPlay();
            }
        }
    }

    /**
     * 回放
     *
     * @param currentTime
     */
    private void playBack(long currentTime) {
        showLoading();
        isPlayback = true;
        if (mUpdateTimeHelper != null)
            mUpdateTimeHelper.stop();
        Log.d(TAG, "playBack:" + CalendarUtil.timeToyyyy_MM_dd_HH_mm_ss(currentTime));
        mPlayer.seekTo(currentTime);
    }

    /**
     * 停止播放
     */
    private void stopPlay() {
        if (!isRelease()) {
            if (!mPlayer.isStop()) {
                Logger.d(TAG, "停止播放");
                mPlayer.stopPlay();
            } else {
                toast("已经停止");
            }

        }
    }

    /**
     * 暂停播放
     */
    private void pausePlay() {
        if (!isRelease()) {
            if (mPlayer.isPlaying()) {
                Logger.d(TAG, "暂停播放");
                mPlayer.pausePlay();
            } else {
                toast("已经暂停");
            }

        }
    }

    /**
     * 释放资源
     */
    private void release() {
        if (!isRelease()) {
            Logger.d(TAG, "释放资源");
            mPlayer.release();
            mPlayer = null;
        }
    }

    private boolean isRelease() {
        if (mPlayer == null) {
            toast("资源已释放");
            return true;
        }
        return false;
    }

    /**
     * 获取token
     *
     * @param callback
     */
    private void getOpenPlatformToken(Callback<Boolean> callback) {
        CameraToken qlyToken = SharedPreferencesUtils.getMonitorToken(mPlayData.getPlayUrl());
        if (qlyToken != null && !qlyToken.isExpired()) {
            QlySdk.setOpenPlatformToken1(qlyToken.getToken(), callback);
            return;
        }
        getTokenFromServer(callback);
    }

    private void getTokenFromServer(Callback<Boolean> callback) {
        String playUrl = mPlayData.getPlayUrl();
        Log.d(TAG, "获取token");
        QlyTokenParams params = new QlyTokenParams();
        params.setAppId(QlyAccount.appId);
        params.setSecret(QlyAccount.secret);
        params.setOperatorType(QlySdk.TOKEN_OPERATOR_TYPE_CUSTOM);
        params.setTargetType(QlySdk.TARGET_TYPE_DEVICE);
        params.setTarget(playUrl);
        params.setAction(QlySdk.ACTION_WRITE);

        QlySdk.getOpenPlatformToken(params, new Callback<CameraToken>() {
            @Override
            public void onSuccess(CameraToken qlyToken) {
                Logger.d(TAG, "获取设备token成功:");
                SharedPreferencesUtils.setMonitorToken(playUrl, qlyToken);
                QlySdk.setOpenPlatformToken1(qlyToken.getToken(), callback);
            }

            @Override
            public void onError(int code, String error) {
                Logger.e(TAG, "获取设备token失败:" + error);
                if (callback != null) {
                    callback.onError(0, error);
                } else {
                    showError(error);
                }
            }
        });
    }

    /**
     * 显示加载框
     */
    private void showLoading() {
        if (mLoading != null) {
            mLoading.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 隐藏加载框
     */
    private void hideLoading() {
        if (mLoading != null) {
            mLoading.setVisibility(View.GONE);
        }
    }

    /**
     * 显示错误信息
     *
     * @param error
     */
    private void showError(String error) {
        if (mTvError != null) {
            mTvError.setText(error);
            mTvError.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 隐藏错误信息
     */
    private void hideError() {
        if (mTvError != null) {
            mTvError.setText(null);
            mTvError.setVisibility(View.GONE);
        }
    }

    /**
     * 设置当前播放的视频的名称
     *
     * @param playData
     */
    private void setPlayName(PlayData playData) {
        if (mTvName != null) {
            mTvName.setText(playData == null ? "playData is null" : playData.getName());
        }
    }

    /**
     * 设置播放按钮的状态
     *
     * @param isPlay
     */
    private void setPlayBtnStatus(boolean isPlay) {
        mPlayBtnStatus = isPlay;
        if (mBtnPlay != null) {
            mBtnPlay.setImageResource(isPlay ? R.drawable.icon_monitor_stop : R.drawable.icon_monitor_play);
        }
    }


    @Override
    protected void onPause() {
        super.onPause();
        stopPlay();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        release();
    }
}
